package com.example.demo.common.aop;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.example.demo.common.util.Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Date;

@Slf4j
@Component
@Aspect
public class TraceIdHandlerAop {
    private static final String TRACE_ID = "traceId";


    @Pointcut("execution(* com.example.demo.modules..*.*(..))")
    public void webLog() {
    }

    /*    @Before("webLog()")
        public void beforeFunc(JoinPoint joinPoint) {
            String traceId = ThreadContext.get("traceId");
            StaticLog.info("traceId========>{}   ", traceId);
            StaticLog.info("before joinPoint========>{}   ", joinPoint);
            StaticLog.info("request params========>{}   ", Utils.tojsonStr(joinPoint.getArgs()));
        }

        @AfterReturning(returning = "ret", pointcut = "webLog()")
        public void doAfterReturning(Object ret) throws Throwable {
            String traceId = ThreadContext.get("traceId");
            StaticLog.info("return ==traceId{}======>{}   ", traceId, ret);
        }*/

    @Around(value = "webLog()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws SQLException {
        String traceId = ThreadContext.get("traceId");
//        StaticLog.info("traceId========>{}   ", traceId);
////        StaticLog.info("方法名称getClass===>{}", proceedingJoinPoint.getClass());
//        StaticLog.info("方法名称getSignature===>{}", proceedingJoinPoint.getSignature());
////        StaticLog.info("方法名称 getSignature.getName===>{}", proceedingJoinPoint.getSignature().getName());
//        StaticLog.info("方法名称入参===>{}", Utils.tojsonStrPlain(proceedingJoinPoint.getArgs()));
        String className=proceedingJoinPoint.getTarget().getClass().getName();
        if(className.indexOf("$Proxy")>=0){  //如果classname带有proxy比如mapper之类的 说明是代理使用 proceedingJoinPoint.getSignature()
            className = proceedingJoinPoint.getSignature().toString();
        }
        Long aLong = Db.use().insertForGeneratedKey(
                Entity.create("project_logs")
                        .set("traceid", traceId)
                        .set("class_sign_name",
                                className+"::"+proceedingJoinPoint.getSignature().getName()) //class+名称
                        .set("params_func", Utils.tojsonStrPlain(proceedingJoinPoint.getArgs())) //参数
                        .set("create_time", Utils.dateFormatYYYYMMddHHmmss(new Date()))
        );
        try {
            Object obj = proceedingJoinPoint.proceed();
//            StaticLog.info("方法名称proceedingJoinPoint.getSignature() return ===>{}", proceedingJoinPoint.getSignature());
//            StaticLog.info("方法名称 params_func ===>{}",  Utils.tojsonStrPlain(proceedingJoinPoint.getArgs()));
//            StaticLog.info("方法名称return ===>{}", Utils.tojsonStrPlain(obj));
            Db.use().update(
                    Entity.create().set("response_func", Utils.tojsonStrPlain(obj)),
                    Entity.create("project_logs").set("id",aLong)

            );
            return obj;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
}
